package com.example.alibabanacosdiscoveryclient;

import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRuleManager;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowItem;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRuleManager;
import com.alibaba.csp.sentinel.slots.system.SystemRule;
import com.alibaba.csp.sentinel.slots.system.SystemRuleManager;
import io.modelcontextprotocol.client.McpClient;
import io.modelcontextprotocol.client.McpSyncClient;
import io.modelcontextprotocol.client.transport.HttpClientSseClientTransport;
import io.modelcontextprotocol.spec.McpSchema;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

@EnableDiscoveryClient
@SpringBootApplication(exclude = {
        org.springframework.ai.mcp.client.autoconfigure.SseHttpClientTransportAutoConfiguration.class
})
@EnableFeignClients
//@EnableScheduling
//@EnableSchedulerLock(defaultLockAtMostFor = "30s")
@MapperScan(value = {"com.example.alibabanacosdiscoveryclient.mapper"})
public class AlibabaNacosDiscoveryClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(AlibabaNacosDiscoveryClientApplication.class, args);
//        initFlowRules();//限流
//        intDegradeRules();//熔断
//        initSystemRule();//系统保护
//        initWhiteRules();//白名单
//        initBlackRules();//黑名单
//        initParamFlowRules();//热点参数
//        testSSE();
    }

    /********************mcp stater***********************************/
//    private static void testSSE() {
//        //该错误忽略，不影响启动
//        HttpClientSseClientTransport transport = new HttpClientSseClientTransport("http://localhost:9001");
//        McpSyncClient client = McpClient.sync(transport).build();
//        client.initialize();
//        // 列出并展示可用的工具
//        McpSchema.ListToolsResult toolsList = client.listTools();
//        System.out.println("可用工具 = " + toolsList);
//        // 获取图书信息
//        McpSchema.CallToolResult result1 = client.callTool(new McpSchema.CallToolRequest("findByName",
//                Map.of("name", "设计")));
//        System.out.println("返回结果: " + result1);
//        System.out.println("---------------------------------------------------------------------------");
//        // 获取城市的天气
//        McpSchema.CallToolResult result2 = client.callTool(new McpSchema.CallToolRequest("getWeather",
//                Map.of("cityName", "北京")));
//        System.out.println("返回结果: " + result2);
//        client.closeGracefully();
//    }

    private String userInput = "找到张三写的书";
    /*
    @Bean
    public CommandLineRunner predefinedQuestions(ChatClient.Builder chatClientBuilder, ToolCallbackProvider tools,
                                                 ConfigurableApplicationContext context) {

        return args -> {

            var chatClient = chatClientBuilder
                    .defaultTools(tools)
                    .build();

            System.out.println("\n>>> QUESTION: " + userInput);
            System.out.println("\n>>> ASSISTANT: " + chatClient.prompt(userInput).call().content());

            context.close();
        };
    }
     */
    private static void initFlowRules() {
        List<FlowRule> flowRules = new ArrayList<FlowRule>();
        FlowRule flowRule = new FlowRule();
        flowRule.setResource("hello");
        flowRule.setCount(10);//每秒不超过10个请求
        flowRule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT);
        flowRule.setStrategy(RuleConstant.STRATEGY_DIRECT);
        flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        flowRule.setLimitApp("default");
        flowRules.add(flowRule);
        FlowRuleManager.loadRules(flowRules);
    }
    private static void intDegradeRules() {
        List<DegradeRule> degradeRules = new ArrayList<DegradeRule>();
        DegradeRule degradeRule1 = new DegradeRule();
        degradeRule1.setResource("hello");
        degradeRule1.setCount(5);
        degradeRule1.setMinRequestAmount(1);
        degradeRule1.setTimeWindow(30);
        degradeRule1.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);
        degradeRule1.setLimitApp("default");
        degradeRules.add(degradeRule1);

//        DegradeRule degradeRule2 = new DegradeRule();
//        degradeRule2.setResource("hello");
//        degradeRule2.setCount(1);
//        degradeRule2.setGrade(RuleConstant.DEGRADE_GRADE_RT);
//        degradeRule2.setSlowRatioThreshold(0.1);
//        degradeRule2.setMinRequestAmount(1);
//        degradeRule2.setTimeWindow(30);
//        degradeRule2.setLimitApp("default");
//        degradeRules.add(degradeRule2);

        DegradeRuleManager.loadRules(degradeRules);
    }
    private static  void initSystemRule() {
        List<SystemRule> rules = new ArrayList<>();
        SystemRule rule = new SystemRule();
        // max load is 3
        rule.setHighestSystemLoad(3.0);
        // max cpu usage is 60%
        rule.setHighestCpuUsage(0.6);
        // max avg rt of all request is 10 ms
        rule.setAvgRt(10);
        // max total qps is 20
        rule.setQps(20);
        // max parallel working thread is 10
        rule.setMaxThread(10);
        rules.add(rule);
        SystemRuleManager.loadRules(rules);
    }
    private static void initWhiteRules() {
        AuthorityRule rule = new AuthorityRule();
        rule.setResource("white");
        rule.setStrategy(RuleConstant.AUTHORITY_WHITE);
        rule.setLimitApp("client");
        AuthorityRuleManager.loadRules(Collections.singletonList(rule));
    }
    private static void initBlackRules() {
        AuthorityRule rule = new AuthorityRule();
        rule.setResource("black");
        rule.setStrategy(RuleConstant.AUTHORITY_BLACK);
        rule.setLimitApp("client");
        AuthorityRuleManager.loadRules(Collections.singletonList(rule));
    }
    private static void initParamFlowRules(){
        ParamFlowRule rule = new ParamFlowRule("hello")
                .setParamIdx(0)//参数索引位置
                .setCount(5);//qps全局阈值5
        //针对string类型的参数 name，单独设置限流 QPS 阈值为 1，而不是全局的阈值 5.
        ParamFlowItem item = new ParamFlowItem().setObject("name")
                .setClassType(String.class.getName())
                .setCount(1);//阈值1
        rule.setParamFlowItemList(Collections.singletonList(item));
        ParamFlowRuleManager.loadRules(Collections.singletonList(rule));
    }
}
